#include <iostream>
#include <sys/select.h>
#include "Sock.hpp"
#define NUM (sizeof(fd_set)*8)
int fd_array[NUM];//内容大于等于0，合法的fd，如果是-1，该位置没有fd
static void Usage(const std::string& proc)
{
    std::cout<<"Usage: "<< proc << " port"<<std::endl;
}
int main(int argc,char* argv[])
{
    if(argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }
    uint16_t port = (uint16_t)atoi(argv[1]);
    int listen_sock = Sock::Socket();
    Sock::Bind(listen_sock,port);
    Sock::Listen(listen_sock);

    for (int i = 0; i < NUM; i++)
    {
        fd_array[i] = -1;
    }

    fd_set rfds;
    fd_array[0] = listen_sock;
    while(true)
    {
        
        FD_ZERO(&rfds);
        int max_fd = fd_array[0];
        for(int i=0;i<NUM;i++)
        {
            if(fd_array[i] == -1) continue;
            FD_SET(fd_array[i],&rfds);
            if(max_fd < fd_array[i])
                max_fd = fd_array[i];
        }

        struct timeval timeout = {5,0};
        int n = select(max_fd+1,&rfds,nullptr,nullptr,nullptr);
        switch (n)
        {
        case -1:
            std::cerr<<"select error"<<std::endl;
            break;
        case 0:
            std::cout<<"select timeout"<<std::endl;
            break;
        default:
            std::cout<<"有fd对应事件就绪了"<<std::endl;
            for(int i=0;i<NUM;i++)
            {
                if(fd_array[i] == -1) continue;
                if(FD_ISSET(fd_array[i],&rfds))
                {
                    std::cout<< "sock: " <<fd_array[i] <<"上面有了读事件"<<std::endl;
                    if(fd_array[i] == listen_sock)
                    {
                        std::cout<< "listen_sock: " <<listen_sock <<"上面有了新链接"<<std::endl;
                        int sock = Sock::Accept(listen_sock);
                        if(sock >=0)
                        {
                            std::cout<< "listen_sock: " <<listen_sock <<"新链接连接成功"<<std::endl;
                            int pos = 1;
                            for(;pos<NUM;pos++)
                            {
                                if(fd_array[pos] == -1) break;
                            }
                            if(pos<NUM)
                            {
                                std::cout<< "新链接: " << sock <<"新链接加入数组"<<std::endl;
                                fd_array[pos] = sock;
                            }
                            else
                            {
                                std::cout<< "服务器满载，关闭新链接"<<std::endl;
                                close(sock);
                            }
                        }
                    }
                    else
                    {
                        // 普通socket读事件
                        char buffer[1024] = {0};
                        ssize_t s = recv(fd_array[i],buffer,sizeof(buffer)-1,0);
                        if (s > 0)
                        {
                            std::cout << "sock: " << fd_array[i] << " 上面有普通读取" << std::endl;
                            buffer[s] = 0;
                            std::cout << "client[ " << fd_array[i] << "]# " << buffer << std::endl;
                        }
                        else if(s == 0)
                        {
                            std::cout << "sock: " << fd_array[i] << "关闭了, client退出啦!" << std::endl;
                            //对端关闭了链接
                            close(fd_array[i]);
                            std::cout << "已经在数组下标fd_array[" << i << "]"
                                      << "中,去掉了sock: " << fd_array[i] << std::endl;
                            fd_array[i] = -1;
                        }
                        else
                        {
                            close(fd_array[i]);
                            std::cout << "已经在数组下标fd_array[" << i << "]"
                                      << "中,去掉了sock: " << fd_array[i] << std::endl;
                            fd_array[i] = -1;
                        }
                        
                    }
                }
            }
            break;
        }
    }
    return 0;
}
